/*
 * Copyright (c) 2011 Ball State University
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * NOTE:
 * Derivative work based on the Google IO 2011 Schedule app released for open source
 * http://code.google.com/p/iosched/
 */

package edu.bsu.android.gtv.apps.bconnected.ui;

import java.util.ArrayList;

import edu.bsu.android.gtv.apps.bconnected.R;
import edu.bsu.android.gtv.apps.bconnected.data.CourseData;
import edu.bsu.android.gtv.apps.bconnected.data.TermData;
import edu.bsu.android.gtv.apps.bconnected.objects.Course;
import edu.bsu.android.gtv.apps.bconnected.objects.Person;
import edu.bsu.android.gtv.apps.bconnected.ui.HomeActivity;
import edu.bsu.android.gtv.apps.bconnected.util.AnalyticsUtils;
import edu.bsu.android.gtv.apps.bconnected.util.Constants;
import edu.bsu.android.gtv.apps.bconnected.util.LoginHelper;
import edu.bsu.android.gtv.apps.bconnected.util.PersistentListFragment;
import edu.bsu.android.gtv.apps.bconnected.util.UIUtils;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

/**
 * A {@link ListFragment} showing a list of courses based on the term selected.  The listfragment appears in the right hand column of the 
 * {@link CourseMultiPaneActivity} after the user selects a term.  Once an item is selected, the {@link CourseInfoActivity} activity
 * is started.
 * @author Kyle Parker, University Computing Services
 */
public class CourseFragment extends PersistentListFragment {
    private static final String TAG = "CourseFragment";
    
	private OnCourseListener mCourseListener = null;
    private CourseAdapter mCourseAdapter;
	private boolean persistentSelection = false;
    private BroadcastReceiver mReceiver;
    
    private ArrayList<Course> mCourses;
    private Activity mActivity;

    private String mLoginGuid;
    private String mBSUID;
    private boolean mLogin;
    private int mTermPosition = 0;
    
	public CourseFragment() {
		this(false);
	}
	
	public CourseFragment(boolean persistentSelection) {
		this.persistentSelection = persistentSelection;
	}
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
		setRetainInstance(true);
    }

	@Override
	public void onActivityCreated(Bundle state) {
		super.onActivityCreated(state);
		
		mActivity = getActivity();
		handleLogout();
		handleLogin();

        AnalyticsUtils.getInstance(mActivity).trackPageView("/Courses");
		registerForContextMenu(getListView());
		restoreState(state);
		
		if (persistentSelection) {
			enablePersistentSelection();
		}

    	mCourses = new ArrayList<Course>();
    	mCourseAdapter = new CourseAdapter(mActivity, R.layout.list_item, mCourses);
        setListAdapter(this.mCourseAdapter);
        setListShown(false);
        
        if (mLogin) {
        	loadCourses();
        }
	}
    
    @Override 
    public void onDestroy() {
    	super.onResume();
    	mActivity.unregisterReceiver(mReceiver);
    }
    
    /** {@inheritDoc} */
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);
		
		if (mCourseListener != null) {
			mCourseListener.onCourseSelected(mCourseAdapter.getItem(position), mTermPosition);
		}
    }

    /**
     * Method called by the ConnectionFragment to launch the activity and set the necessary values for the web service calls
     * @param position
     */
    public void startActivity(final int position) {
    	mTermPosition = position;
    	
    	if (mActivity != null) {
    		loadCourses();
    	}
    }
    
    /**
     * Using a new thread, separate from the main activity, load the course information from the service handler
     */
    private void loadCourses() {
        Runnable load = new Runnable(){
            public void run() {
            	try { 
            		if (TermData.getTermCount() == 0) {
                        TermData.initializeTerm(mActivity);
            		}
            		
	    	    	String termID = TermData.getTerm(mTermPosition).getTermID();

	    	    	CourseData.initializeCourse(mBSUID, termID, mLoginGuid, mActivity);

	                if (CourseData.getCourseCount() > 0) {
	                	mCourses = CourseData.getCourses();
	                } else {
	                	mCourses = null;
	                }
                    
            		mActivity.runOnUiThread(returnCourse);
            	} catch (Exception ex) {
                    AnalyticsUtils.getInstance(mActivity).trackPageView(TAG + ": " + ex.getMessage());
            	}
            }
        };
        
        Thread thread = new Thread(null, load, "loadCourses");
        thread.start();
        
        if (mActivity != null) {
        	setListShown(false);
        }
    }
    
    /**
     * Add each course object from the service handler to the array adapter and set the visibility of the spinner to "gone"
     */
    private Runnable returnCourse = new Runnable(){
        public void run() {
        	if (mCourseAdapter.getCount() > 0) {
        		mCourseAdapter.clear();
        	}
        	
        	// If the call to the classmate service did not return the "error" attribute, then display the classmates, otherwise 
        	// the expiration date has expired for the user or they are not authorized under the current credentials to access the information.
        	// When retrieving data from the .NET service handler, the BSU ID and login guid are matched against the SQL Server database.  If
        	// the combination of the two do not match, then the user is not permitted to retrieve the requested data.  The guards against
        	// someone hacking the querystring parameters to retrieve the information of another student.
        	if (CourseData.getCourseAuth()) {
	            if (mCourses != null && mCourses.size() > 0) {
	            	Log.i("Size", Integer.toString(mCourses.size()));
	                for(int i=0; i < mCourses.size(); i++)
	                {
	                	mCourseAdapter.add(mCourses.get(i));
	                }
	                
	                // If there are items, the list needs to enabled (or re-enabled in the event a blank list was loaded initially)
	            	getListView().setEnabled(true);
	            } else {
	            	Course empty = new Course();
	            	empty.setError(mActivity.getString(R.string.empty_course));
	            	mCourseAdapter.add(empty);
	            	
	            	// If there are no items returned, disable the list selection
	            	getListView().setEnabled(false);
	            }
        	} else {
            	Course error = new Course();
            	error.setError(mActivity.getString(R.string.error_auth));
            	mCourseAdapter.add(error);
            	
            	// If there was an error authorizing the student, display the error message and disable the list
            	getListView().setEnabled(false);
        	}

            mCourseAdapter.notifyDataSetChanged();
            setListShown(true);
        }
    };

    /**
     * CourseAdapter used to populate the listview for the courses
     */
    private class CourseAdapter extends ArrayAdapter<Course> {
        private ArrayList<Course> items;

        public CourseAdapter(Context context, int textViewResourceId, ArrayList<Course> items) {
            super(context, textViewResourceId, items);
            this.items = items;
        }
        
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {               	
            View view = convertView;
            
            if (view == null) {
            	view = LayoutInflater.from(mActivity).inflate(R.layout.list_item_secondary, null);
            } 
            
            Course course = items.get(position);    
            
            if (course != null) {
            	if (course.getError() != null) {
                	UIUtils.displayTextView(view, R.id.item, course.getError());
            	} else {
                	UIUtils.displayTextView(view, R.id.item, course.getCourseWithTitle()); 
            	}         	
            }
            
            return view;
        }
    }
    
	public void setOnCourseListener(OnCourseListener listener) {
		this.mCourseListener = listener;
	}	
	
	public interface OnCourseListener {
		void onCourseSelected(Course course, int termPosition);
	}

    /**
     * In order to protect the activity from the back stack after a student logs out, remove the activity 
     * If the student hits the back button, this will take them to the Home activity
     */
    private void handleLogout() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Constants.ACTION_LOGOUT);
        mReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
			    Log.d("onReceive","Logout in progress");
		        intent = new Intent(Intent.ACTION_VIEW, null, mActivity, HomeActivity.class);
		        intent.putExtra(Constants.EXTRA_LOGIN_STATUS, Integer.toString(Constants.LOGIN_STATUS_LOGOUT));
		        
		        mActivity.startActivity(intent); 
			    mActivity.finish();
			}
		};
		
        mActivity.registerReceiver(mReceiver, intentFilter);
    }
    
    /**
     * Determine if the person has logged in and whether there is a person object in the database
     * Get the student's BSU ID for use throughout the application
     */
    private void handleLogin() {
    	Person person = LoginHelper.checkLogin(mActivity);
    	
    	if (person != null) {
    		mBSUID = person.getBSUID();
        	mLoginGuid = person.getLoginGuid();
        	
        	mLogin = true;
    	} else {
	        Intent intent = new Intent(Intent.ACTION_VIEW, null, mActivity, HomeActivity.class);
	        intent.putExtra(Constants.EXTRA_LOGIN_STATUS, Integer.toString(Constants.LOGIN_STATUS_NOT_LOGGED_IN));
	        
	        mActivity.startActivity(intent); 
		    mActivity.finish();
		    
		    mLogin = false;
    	}    	
    }
}
